/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: Dec 31, 2009
 * Time: 10:57:49 AM
 * To change this template use File | Settings | File Templates.
 */
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import org.jdom.*;
import org.jdom.input.SAXBuilder;

public class Template
{

    public Template(String s, URL url, String s1)
        throws JDOMException, MalformedURLException, IOException
    {
        s = "<xml xmlns:sg=\"http://www.brics.dk/jwig/gap\" xmlns=\"" + s1 + "\">" + s + "</xml>";
        xml = makeDocument(s, url).getRootElement().getContent();
        attribute_gaps = new HashSet();
        template_gaps = new HashSet();
        addGaps(xml);
    }

    public Template(List list)
    {
        xml = list;
        attribute_gaps = new HashSet();
        template_gaps = new HashSet();
        addGaps(list);
    }

    private void fixForms(List list)
    {
        Iterator iterator = list.iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Object obj = iterator.next();
            if(obj instanceof Element)
            {
                Element element = (Element)obj;
                if(!isGap(element))
                {
                    if(element.getName().equals("form") && element.getAttribute("action") == null && element.getAttribute("action", Namespace.getNamespace("sg", "http://www.brics.dk/jwig/gap")) == null)
                        element.setAttribute("action", "dummy");
                    fixForms(element.getChildren());
                }
            }
        } while(true);
    }

    public void fixForms()
    {
        fixForms(xml);
    }

    private void fixAnchors(List list)
    {
        Iterator iterator = list.iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Object obj = iterator.next();
            if(obj instanceof Element)
            {
                Element element = (Element)obj;
                if(!isGap(element))
                {
                    if(element.getName().equals("a") && (element.getAttribute("submit") != null || element.getAttribute("submit", Namespace.getNamespace("sg", "http://www.brics.dk/jwig/gap")) != null))
                    {
                        element.removeAttribute("submit");
                        element.removeAttribute("submit", Namespace.getNamespace("sg", "http://www.brics.dk/jwig/gap"));
                        element.removeAttribute("status");
                        element.removeAttribute("status", Namespace.getNamespace("sg", "http://www.brics.dk/jwig/gap"));
                        element.setAttribute("href", "dummy");
                    }
                    fixAnchors(element.getChildren());
                }
            }
        } while(true);
    }

    public void fixAnchors()
    {
        fixAnchors(xml);
    }

    void addGaps(List list)
    {
        Iterator iterator = list.iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Object obj = iterator.next();
            if(obj instanceof Element)
            {
                Element element = (Element)obj;
                Iterator iterator1 = element.getAttributes().iterator();
                do
                {
                    if(!iterator1.hasNext())
                        break;
                    Attribute attribute = (Attribute)iterator1.next();
                    if(isGap(attribute))
                        attribute_gaps.add(getGap(attribute));
                } while(true);
                if(isGap(element))
                    template_gaps.add(getGap(element));
                else
                    addGaps(element.getChildren());
            }
        } while(true);
    }

    public static Document makeDocument(String s, URL url)
        throws JDOMException, MalformedURLException, IOException
    {
        Document document = (new SAXBuilder()).build(new StringReader(s));
        expand(document.getRootElement(), url, new Stack(), new HashSet());
        return document;
    }

    public static Document makeDocument(URL url)
        throws JDOMException, MalformedURLException, IOException
    {
        return makeDocument(url, new Stack(), new HashSet(), true);
    }

    private static Document makeDocument(URL url, Stack stack, Set set, boolean flag)
        throws JDOMException, MalformedURLException, IOException
    {
        if(stack.search(url) != -1)
            throw new JDOMException("cyclic XInclude: " + url);
        if(set.contains(url))
            return null;
        Document document = (new SAXBuilder()).build(url);
        if(!flag)
            stack.push(url);
        else
            set.add(url);
        expand(document.getRootElement(), url, stack, set);
        if(!flag)
            stack.pop();
        return document;
    }

    private static void expand(Element element, URL url, Stack stack, Set set)
        throws JDOMException, MalformedURLException, IOException
    {
        if(element.getNamespaceURI().equals("http://www.brics.dk/DSD/2.0") && element.getName().equals("import"))
        {
            String s = element.getAttributeValue("href");
            if(s == null)
                throw new JDOMException("invalid import element, href attribute missing");
            URL url1;
            if(url == null)
                url1 = new URL(s);
            else
                url1 = new URL(url, s);
            Document document = makeDocument(url1, stack, set, true);
            if(document != null)
                replace(element, document.getRootElement());
            else
                replace(element, null);
        } else
        if(element.getNamespaceURI().equals("http://www.w3.org/2001/XInclude") && element.getName().equals("include"))
        {
            String s1 = element.getAttributeValue("href");
            if(s1 == null)
                throw new JDOMException("invalid XInclude element, href attribute missing");
            URL url2;
            if(url == null)
                url2 = new URL(s1);
            else
                url2 = new URL(url, s1);
            replace(element, makeDocument(url2, stack, set, false).getRootElement());
        } else
        {
            List list = element.getContent();
            for(int i = 0; i < list.size(); i++)
            {
                Object obj = list.get(i);
                if(obj instanceof Element)
                    expand((Element)obj, url, stack, set);
            }

        }
    }

    private static void replace(Element element, Element element1)
    {
        if(element1 != null)
            element1.detach();
        Element element2 = (Element)element.getParent();
        Document document = element.getDocument();
        Iterator iterator;
        if(element2 == null)
            iterator = document.getContent().iterator();
        else
            iterator = element2.getContent().iterator();
        ArrayList arraylist = new ArrayList();
        do
        {
            if(!iterator.hasNext())
                break;
            Object obj = iterator.next();
            iterator.remove();
            if(obj == element)
            {
                if(element1 != null)
                    arraylist.add(element1);
            } else
            {
                arraylist.add(obj);
            }
        } while(true);
        if(element2 == null)
            document.setContent(arraylist);
        else
            element2.setContent(arraylist);
    }

    public List getXML()
    {
        return xml;
    }

    public Set getAttributeGaps()
    {
        return attribute_gaps;
    }

    public Set getTemplateGaps()
    {
        return template_gaps;
    }

    public static boolean isGap(Attribute attribute)
    {
        return attribute.getNamespaceURI().equals("http://www.brics.dk/jwig/gap");
    }

    public static boolean isGap(Element element)
    {
        return element.getNamespaceURI().equals("http://www.brics.dk/jwig/gap");
    }

    public static Namespace getGapNamespace()
    {
        return Namespace.getNamespace("http://www.brics.dk/jwig/gap");
    }

    public static String getGap(Element element)
    {
        return element.getName();
    }

    public static String getGap(Attribute attribute)
    {
        return attribute.getValue();
    }

    private void increment(HashMap hashmap, String s)
    {
        Integer integer = (Integer)hashmap.get(s);
        if(integer == null)
            hashmap.put(s, new Integer(1));
        else
        if(integer.intValue() == 1 || integer.intValue() == 3)
            hashmap.put(s, new Integer(2));
    }

    private void star(HashMap hashmap, String s)
    {
        hashmap.put(s, new Integer(2));
    }

    private void incrementDiamond(HashMap hashmap, String s)
    {
        Integer integer = (Integer)hashmap.get(s);
        if(integer == null)
            hashmap.put(s, new Integer(3));
        else
        if(integer.intValue() == 1)
            hashmap.put(s, new Integer(2));
    }

    private void outGaps(List list, HashMap hashmap)
    {
        Iterator iterator = list.iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Object obj = iterator.next();
            if(obj instanceof Element)
            {
                Element element = (Element)obj;
                if(isGap(element))
                {
                    increment(hashmap, getGap(element));
                } else
                {
                    Iterator iterator1 = element.getAttributes().iterator();
                    do
                    {
                        if(!iterator1.hasNext())
                            break;
                        Attribute attribute = (Attribute)iterator1.next();
                        if(isGap(attribute))
                            increment(hashmap, getGap(attribute));
                    } while(true);
                    outGaps(element.getChildren(), hashmap);
                }
            }
        } while(true);
    }

    public HashMap outGaps()
    {
        HashMap hashmap = new HashMap();
        outGaps(xml, hashmap);
        return hashmap;
    }

    private void inGaps(List list, List list1, String s)
    {
        Iterator iterator = list.iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Object obj = iterator.next();
            if(obj instanceof Element)
            {
                Element element = (Element)obj;
                if(!isGap(element))
                    if(element.getName().equals("form"))
                    {
                        if(s.equals(element.getAttributeValue("action")))
                        {
                            HashMap hashmap = new HashMap();
                            outGaps(element.getChildren(), hashmap);
                            list1.add(hashmap);
                        }
                    } else
                    {
                        inGaps(element.getChildren(), list1, s);
                    }
            }
        } while(true);
    }

    public List inGaps(String s)
    {
        ArrayList arraylist = new ArrayList();
        inGaps(xml, ((List) (arraylist)), s);
        return arraylist;
    }

    private void outFields(List list, HashMap hashmap, Set set)
    {
        Namespace namespace = Namespace.getNamespace("sg", "http://www.brics.dk/jwig/gap");
        Iterator iterator = list.iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Object obj = iterator.next();
            if(obj instanceof Element)
            {
                Element element = (Element)obj;
                if(!isGap(element))
                {
                    String s = element.getName();
                    if(s.equals("input") || s.equals("button") || s.equals("select") || s.equals("textarea") || s.equals("object"))
                    {
                        String s1 = element.getAttributeValue("name");
                        String s2 = element.getAttributeValue("type");
                        String s3 = element.getAttributeValue("multiple");
                        String s4 = element.getAttributeValue("disabled");
                        String s5 = element.getAttributeValue("declare");
                        Attribute attribute = element.getAttribute("disabled", namespace);
                        Attribute attribute1 = element.getAttribute("declare", namespace);
                        if(s2 != null && s2.equals("radio"))
                            incrementDiamond(hashmap, s1);
                        else
                        if(s1 != null && (s2 == null || !s2.equals("reset") && !s2.equals("submit") && !s2.equals("image")) && s4 == null && s5 == null && (attribute == null || set.contains(getGap(attribute))) && (attribute1 == null || set.contains(getGap(attribute1))))
                            if(s3 != null || s2 != null && s2.equals("checkbox") || attribute != null && set.contains(getGap(attribute)) || attribute1 != null && set.contains(getGap(attribute1)))
                                star(hashmap, s1);
                            else
                                increment(hashmap, s1);
                    } else
                    {
                        outFields(element.getChildren(), hashmap, set);
                    }
                }
            }
        } while(true);
    }

    public HashMap outFields(Set set)
    {
        HashMap hashmap = new HashMap();
        outFields(xml, hashmap, set);
        return hashmap;
    }

    private void inFields(List list, List list1, Set set, String s)
    {
        Iterator iterator = list.iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Object obj = iterator.next();
            if(obj instanceof Element)
            {
                Element element = (Element)obj;
                if(!isGap(element))
                    if(element.getName().equals("form"))
                    {
                        if(s.equals(element.getAttributeValue("action")))
                        {
                            HashMap hashmap = new HashMap();
                            outFields(element.getChildren(), hashmap, set);
                            list1.add(hashmap);
                        }
                    } else
                    {
                        inFields(element.getChildren(), list1, set, s);
                    }
            }
        } while(true);
    }

    public List inFields(Set set, String s)
    {
        ArrayList arraylist = new ArrayList();
        inFields(xml, ((List) (arraylist)), set, s);
        return arraylist;
    }

    public static final int ZERO = 0;
    public static final int ONE = 1;
    public static final int STAR = 2;
    public static final int DIAMOND = 3;
    List xml;
    HashSet attribute_gaps;
    HashSet template_gaps;
    private static final String gap_namespace = "http://www.brics.dk/jwig/gap";
}

